package com.zbmy.plugin.im.server.core.back.server.codec;

import com.zbmy.plugin.im.server.core.protocol.MessageHolder;
import com.zbmy.plugin.im.server.core.protocol.ProtocolHeader;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;

/**
 * 
 * LengthFieldBasedFrameDecoder消息解码器（自动处理毡包问题）
 * @ClassName: PacketLengthFieldDecoder    
 * @author 杨乐平    
 * @date 2018年5月2日 上午11:10:21    
 * @version  v 1.0
 */
public class BackPacketLengthFieldDecoder extends LengthFieldBasedFrameDecoder{
	private static final int HEADER_SIZE = 6;
	
	public BackPacketLengthFieldDecoder(int maxFrameLength, int lengthFieldOffset,
			 int lengthFieldLength, int lengthAdjustment,
			 int initialBytesToStrip) {
		super(maxFrameLength, lengthFieldOffset, lengthFieldLength, lengthAdjustment,
				initialBytesToStrip);
	}
	
	@Override
    protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
        //在这里调用父类的方法,实现指得到想要的部分,我在这里全部都要,也可以只要body部分
        in = (ByteBuf) super.decode(ctx,in);  
        if(in == null){
            return null;
        }
        if(in.readableBytes()<HEADER_SIZE){
            throw new Exception("字节数不足");
        }
        short magic = in.readShort();
        if (magic != ProtocolHeader.MAGIC) {  // 数据包的验证位，必须为0xabcd 2位
            // Magic不一致，表明不是自己的数据
            //logger.info("Magic不一致");
            //in.resetReaderIndex();			// 因为处理出现异常，需要回到原来完整得包位置，表示没读过。下次进来还是一样得
            throw new Exception("校验码不对");
        }
     // 开始解码
        byte sign = in.readByte();		// 读取下一个字节，消息标志，请求／响应／通知，byte类型
        byte type = in.readByte();		// 读取下一个字节，消息类型，登录／发送消息等，byte类型
        byte status = in.readByte();	// 响应状态，成功／失败，byte类型
        // 确认消息体长度
        int bodyLength = in.readInt();	// 4个字节消息长度
        if(in.readableBytes()!=bodyLength){
            throw new Exception("标记的长度不符合实际长度");
        }
        //读取body
        byte []bytes = new byte[in.readableBytes()];
        in.readBytes(bytes);
        //return new MyProtocolBean(type,flag,length,new String(bytes,"UTF-8"));
        MessageHolder messageHolder = new MessageHolder();
        messageHolder.setType(type);
        messageHolder.setSign(sign);
        messageHolder.setStatus(status);
        messageHolder.setBody(new String(bytes, "utf-8"));
        return messageHolder;
    }
}
